Shakespeare would have called it the dark backward and abysm of time—the dimly remembered, pre-Win95 days of yestermonth—when Visual Basic programmers who wanted to explore and manipulate the network resources underlying their applications
were forced to link to the network provider's own Windows DLLs (Novell's NWNETAPI.DLL, for example), assuming these even were available. As you might imagine, this method of LAN resource management is at best tolerable—when a network consists of a
single provider protocol. But in today's world, where it is not uncommon for a LAN (or WAN) to include two, three, or more distinct network protocols, this scheme becomes ponderous if not wholly unworkable.
With the introduction of Windows 95 and Windows NT, the creation and management of multi-protocol networks (as well as the creation of Windows applications to take full advantage of them) has been simplified greatly. A variety of network protocols and
services can coexist under Windows 95 or NT, with no notion of primary or secondary networking software. Remote disk drives and printers can each be served by different network protocols—all under the watchful eye of the Win32 API. Under Windows 95,
for example, drive E could be on a Windows NT server, drive G could be a NetWare server, and drive W could be a CD-ROM on a Sun Systems workstation across a WAN. The difference between local and network printers similarly has disappeared. The Win32 API
offers the same basic programming interface for networking, regardless of the underlying software protocol and topology.
What this means to you, the Visual Basic programmer, is that your 32-Bit Visual Basic programs can call the network functions in the Microsoft Win32 application programming interface (API). These functions enable you to implement networking capabilities
without making adjustments for a particular protocol provider or physical network configuration. In other words, the Win32 network functions are network independent. Your Visual Basic applications can use these functions to add and cancel network
connections and to retrieve information about the current configuration of the physical network. In addition, the Win32 API implements a version of the NetBIOS network interface for applications that require it.
In this chapter, you'll be introduced to a dozen or so Win32 API functions (the Windows Network or WNet* functions) that can be called from your Visual Basic applications. (The asterisk in WNet* is a wild card character, indicating that all the function
names begin with the same four letters.) But first, in order to familiarize yourself with the network jargon you'll encounter, take a look at Figure 38.1, which shows the structure of a typical multi-provider network.
FIGURE 38.1. A typical multi-provider network.
In Figure 38.1, the hierarchy for Microsoft Advanced Server resources is shown in detail as Network provider #2. Network resources from other providers (#1 might be Novell, for example, while #3 is Banyan) have different hierarchical systems. However,
your Visual Basic application does not need information about the hierarchy before it begins to work with a network. It can proceed from the network root (that is, the topmost container resource) and retrieve information about the network's other resources
as that information is required. Resources that do not contain other resources are regarded as objects. Sharepoint #1 and sharepoint #2 in Figure 38.1 are objects. A sharepoint is an object accessible across the network, such as a printer or shared
directory.
Windows 3.1 (and Windows For Workgroups) included the following protocol-independent network management functions (they did not, however, take advantage of 32-bit architecture):
The Win32 API supports these functions and has added the following network and network resource enumeration functions:
Your Visual Basic applications can use these network functions to browse, add, or cancel network connections anywhere in the hierarchy. By starting at the network root, the resources from all network providers can be listed for documentation or
manipulation.
The Windows network functions enable your application to explore and manage network connections directly, or to give direct control of the network connections to your users. To call these functions, you must link to the multiple-provider router library
(MPR.LIB). The following section discusses and demonstrates how to use many of these functions in your Visual Basic applications.
First, start a new Visual Basic project, add a new standard code module, and name it VBUCODE. Next, you'll add some function declarations to your new module with the help of the API Text Viewer. The API Text Viewer is a great little tool included with
Visual Basic 4.0. You can use it to paste long and cumbersome function declarations, constants, and custom data types into your Visual Basic modules. The API Text Viewer is located in the Visual Basic 4.0 group. In fact, there may be two of them there: one
for 16-bit development and one for 32-bit projects. In this chapter, you'll be working with the Win32 API. From the Viewer's File menu, select Load Text File and load Win32Api.Txt. This process takes a while, so be patient. There's a lot of stuff here.
After the file is loaded, select Declares from the API Type drop-down list. In the Available Items list, locate WNetAddConnection and double-click it to add it to the Selected Items list. Do the same for WNetCancelConnection. Your screen should look
something like Figure 38.2.
FIGURE 38.2. The Win32 API Text Viewer.
After the functions are selected in the Selected Items list, click the Copy button to copy them to the Clipboard. Then switch to your VBUCODE module and paste them in. That's all there is to it. This way, you're ensured of getting an accurate
declaration, no matter how long and cumbersome the statement. Just minimize the API Text Viewer for now—you'll need it again later.
The next step is to rename your project's default form (Form1) to something a little more descriptive—frmVBNet, for example. This form will provide an interface for connecting to, and disconnecting from, network resources.
Figure 38.3 shows how the Visual Basic IDE (Integrated Development Environment), including frmVBNet, will look once you've completed the form's visual implementation.
FIGURE 38.3. The Connecting to Network Resources dialog box.
Now complete the visual design of your new form, referring to Table 38.1 for significant objects and suggested settings.
Visual Basic Object |
Property |
Design Time Setting |
Form |
Name Caption |
frmVBNet Connecting To Network Resources |
TextBox |
Name |
txtNetPath |
TextBox |
Name |
txtDrive |
TextBox |
Name |
txtPassWord |
Drive List Box |
Name |
Drive1 |
Command Button |
Name Caption Default |
cmdConnect &Connect True |
Command Button |
Name Caption |
cmdDisconnect &Disconnect |
As you probably have surmised, this form enables the user to connect to a network resource, such as a shared directory, by providing the resource's network path and an available drive letter. Because some network resources might be password protected,
there's also a TextBox control for entering the password. The DriveList control will be used to verify a successful connection, as well as to select a current resource for disconnection.
You've already DECLARED the WNetAddConnection and WNetCancelConnection functions you'll need. Now it's time to take a closer look at these functions, and to put them into action.
This function enables your application to connect a local device to a network resource. A successful connection is always persistent, meaning that Windows automatically attempts to restore the connection at the next logon. Here's the syntax, followed by
a discussion of the parameters and possible error conditions:
lngRetVal = WNetAddConnection(strRemoteName,strPassword,strLocalName)
Here, the strRemoteName parameter is a string variable that specifies the complete path to the desired network resource. The parameter strPassword specifies the password to be used to make a connection, if one is required. This parameter is usually the
password associated with the current user. If the string is empty, no password is used. The last parameter, strLocalName, is a string variable that identifies the name of the local device to be redirected, such as F or LPT1. If this string is NULL, a
connection to the network resource is made, but no local device is redirected.
If the connection is successful, the value returned by this function, lngRetVal, is equal to the value of the constant ERROR_SUCCESS (which can be located, along with any other constants mentioned in this chapter, under Constants in the API Text Viewer
and pasted into your VBUCODE module).
If the function fails and no connection is made, the return value is an error code constant. Table 38.2 lists the most likely error codes for the WNetAddConnection function.
Constant |
Meaning |
ERROR_ACCESS_DENIED |
Access is denied |
ERROR_ALREADY_ASSIGNED |
The device specified in the strLocalName parameter already is connected |
ERROR_BAD_DEV_TYPE |
The device type and the resource type do not match |
ERROR_BAD_DEVICE |
Value specified in strLocalName is invalid |
ERROR_BAD_NET_NAME |
Value specified in the strRemoteName parameter is not valid or cannot be located. |
ERROR_BAD_PROFILE |
User profile is in an incorrect format |
ERROR_CANNOT_OPEN_PROFILE |
System is unable to open the user profile to process persistent connections |
ERROR_DEVICE_ALREADY_REMEMBERED |
An entry for the device specified in strLocalName is already in the user profile |
ERROR_EXTENDED_ERROR |
A network-specific error occurred |
ERROR_INVALID_PASSWORD |
Specified password is invalid |
ERROR_NO_NET_OR_BAD_PATH |
Operation cannot be performed because either a network component is not started or the specified name cannot be used |
ERROR_NO_NETWORK |
No network is present |
This simple function breaks an existing network connection. Here's its syntax:
lngRetVal = WNetCancelConnection(strName,bForce)
Here, the parameter strName is a string variable containing the name of the redirected local device (F or LPT1, for example) or the network resource to be disconnected. When strName specifies a redirected local device, only the specified redirection is
broken, and Windows will not restore the connection during ensuing logon operations. When this parameter specifies a remote network resource, the connection to that remote network resource is broken.
The bForce parameter is a Boolean value indicating whether the disconnection is to occur even if there are open files or uncompleted jobs on the connection. If this parameter is FALSE, the function fails if there are open files or jobs, and an
appropriate error code is returned.
If the function succeeds, the return value, lngRetVal, is ERROR_SUCCESS. If the function fails, the return value may be an error listed in Table 38.2 or Table 38.3.
Constant |
Meaning |
ERROR_DEVICE_IN_USE |
The specified device is in use by an active process and cannot be disconnected |
ERROR_NOT_CONNECTED |
The name specified by the strName parameter is not a redirected device, or the system is not currently connected to the device specified by the parameter |
ERROR_OPEN_FILES |
There are open files or uncompleted processes, and the bForce parameter is FALSE |
It's time to add some spark to your new Network Connection form. The action occurs when cmdConnect or cmdDisconnect is clicked. Listings 38.1 and 38.2 are the documented listings for those two event procedures.
Private Sub cmdConnect_Click() Dim ServerText As String, PassWordText As String ' Useful variables Dim DriveLetter As String Dim Msg As String ' For returned error message. Dim Succeed As Long ' For long value returned by functions. ServerText = UCase$(txtNetPath) ' Network resource name PassWordText = txtPassWord ' Password for the resource DriveLetter = txtDrive ' Get drive letter Succeed = WNetAddConnection(ServerText, PassWordText, DriveLetter) If IsSuccess(Succeed, Msg) = True Then ' Call custom function ' with returned value ' to test for success ' and/or get error message. Drive1.Refresh ' If successful connect, ' show new connection in ' drive list box. Else ' Function not successful MsgBox Msg, , "Visual Basic Unleashed!" ' so display error. End If End Sub
Listing 38.2 shows the code to be added to cmdDisconnect's Click event. Notice that you select the drive to be disconnected by picking it from the DriveList drop-down list.
Private Sub cmdDisconnect_Click() Dim DriveLetter As String, Msg As String Dim Succeed As Long DriveLetter = Mid$(Drive1.Drive, 1, 2) ' Get drive letter. Succeed = WNetCancelConnection(DriveLetter, True) ' Send it to the ' CancelConnection ' function, along ' with a TRUE to ' force the ' disconnect, even ' with open files ' and/or processes. If IsSuccess(Succeed, Msg) = True Then ' If successful, Drive1.Refresh ' refresh drive list Else MsgBox Msg, , "Visual Basic Unleashed!" ' Otherwise, display ' the error message. End If End Sub
Listing 38.3 shows the IsSuccess() function, which is really just a specialized error handler. This code should be added to your VBUCODE module.
Function IsSuccess(ReturnCode As Long, Msg As String) As Boolean If ReturnCode = ERROR_SUCCESS Then IsSuccess = True Else IsSuccess = False Select Case ReturnCode Case ERROR_INVALID_FUNCTION: Msg = "Function is not supported." Case ERROR_OUTOFMEMORY: Msg = "Out of Memory." Case ERROR_BAD_NET_NAME: Msg = "Invalid Network Resource Name." Case ERROR_NO_RESOURCE_NAME: Msg = "Must Enter A Valid Network Resource Name." Case ERROR_INVALID_PASSWORD: Msg = "The Password was Invalid." Case ERROR_ACCESS_DENIED: Msg = "A Security Violation Occurred." Case ERROR_ALREADY_CONNECTED: Msg = "Local Device Already Connected." Case ERROR_CONNECTION_UNAVAIL: Msg = "The Resource Is Not Shared." Case ERROR_ALREADY_ASSIGNED: Msg = "Local Drive Identifier Is In Use." Case ERROR_BAD_USERNAME: Msg = "No Such User." Case ERROR_INVALID_PRINTER_NAME: Msg = "No Such Printer." Case ERROR_LOCAL_DRIVE: Msg = "Can't Disconnect Local Drive." Case ERROR_INTERNAL_ERROR: Msg = "Internal Error!" Case Else: Msg = "Unrecognized Error " + Str$(ReturnCode) + "." End Select End If End Function
Finally, you'll need to set up the ERROR constants referred to in the IsSuccess() function. Add the lines shown in Listing 38.4 to your VBUCODE module, using the API Text Viewer if you find it easier.
Public Const ERROR_SUCCESS = 0& Public Const ERROR_INVALID_FUNCTION = 1& Public Const ERROR_ACCESS_DENIED = 5& Public Const ERROR_OUTOFMEMORY = 14& Public Const ERROR_ALREADY_CONNECTED = 52& Public Const ERROR_BAD_NETPATH = 53& Public Const ERROR_UNSHARED_RESOURCE = 67& Public Const ERROR_BAD_NET_NAME = 67& Public Const ERROR_ALREADY_ASSIGNED = 85& Public Const ERROR_INVALID_PASSWORD = 86& Public Const ERROR_BUFFER_OVERFLOW = 111& Public Const ERROR_BAD_PATHNAME = 161& Public Const ERROR_ALREADY_EXISTS = 183& Public Const ERROR_NO_RESOURCE_NAME = 487& Public Const ERROR_CONNECTION_UNAVAIL = 1201& Public Const ERROR_BAD_PROVIDER = 1204& Public Const ERROR_BAD_PROFILE = 1206& Public Const ERROR_EXTENDED_ERROR = 1208& Public Const ERROR_INVALID_PASSWORDNAME = 1216& Public Const ERROR_INTERNAL_ERROR = 1359& Public Const ERROR_INVALID_PRINTER_NAME = 1801& Public Const ERROR_BAD_USERNAME = 2202& Public Const ERROR_LOCAL_DRIVE = 2250&
It's time to test your form, assuming that you're working in a network environment. Be sure frmVBNet is your project's StartUp form, and then run your program. Test your form by trying various connections and disconnections. If the functions are not
successful, you should get an appropriate error message. If they are successful, you'll be able to drop down the DriveList box and verify the connection, or disconnection, as the case may be.
Figure 38.4 shows a sample session where the connection was successful.
In Figure 38.5, you see the results of an attempt to connect to an unshared directory.
FIGURE 38.4. The Network Connection form in action.
FIGURE 38.5. A failed connection attempt.
One of the disadvantages of plain ol' WNetAddConnection is that you have no control over the type of connection you make—that is, whether it's persistent. (Remember that a persistent connection is one that is "remembered" by Windows, and
is automatically re-established at the next logon. Connections made with WNetAddConnection are persistent.)
Using WNetAddConnection2, you can specify a persistent connection or one that is valid only for the current session. The price you pay for this is a little more complexity in making the call. As you'll see in the following discussion, WNetAddConnection2
requires a custom data type, NETRESOURCE, as one of its parameters. You need to add the type definition and constants shown in Listing 38.5 to your VBUCODE module.
Type NETRESOURCE lngScope As Long ' To specify scope during enumeration. lngType As Long ' Defines the type of resource. lngDisplayType As Long ' How resources will be displayed. lngUsage As Long ' Specifies the resource usage. strLocalName As String ' Local device for the connection. strRemoteName As String ' Indicates the network resource. strComment As String ' For a provider-supplied comment. strProvider As String ' Name of provider who owns the resource. End Type Public Const RESOURCETYPE_ANY = &H0 ' These are some useful Public Const RESOURCETYPE_DISK = &H1 ' constants to be used Public Const RESOURCETYPE_PRINT = &H2 ' with many of the WNet Public Const RESOURCETYPE_UNKNOWN = &HFFFF ' functions. Public Const CONNECT_UPDATE_PROFILE = &H1
Now here's the syntax for WNetAddConnection2, followed by a detailed discussion of all its parameters:
lngRetVal=WNetAddConnection2(nrCon,strPassword,strUserName,lngConnect)
The first parameter, nrCon, is a NETRESOURCE structure (in Visual Basic, a custom data type) that provides details of the proposed connection. It contains information about the network resource, the local device to be redirected, and the network
resource provider. When calling WNetAddConnection2, you must specify the members of the NETRESOURCE data type shown in Table 38.4.
Member |
Description |
lngType |
Specifies the type of network resource to connect to. If strLocalName points to a non-empty string, this member can be one of the constants RESOURCETYPE_DISK or RESOURCETYPE_PRINT. If strLocalName is NULL or empty, lngType can be RESOURCETYPE_DISK, RESOURCETYPE_PRINT, or RESOURCETYPE_ANY. |
strLocalName |
A string that specifies the name of a local device to be redirected, such as "X:" or "COM1". The case of the string is unimportant. If the string is empty or NULL, the function makes a connection but does not redirect the resource to a local device. |
strRemoteName |
A string that specifies the network resource to connect to. This string must adhere to the network provider's naming conventions. |
strProvider |
Specifies the network provider to connect to. If strProvider is NULL or empty, the operating system attempts to determine the correct provider by parsing the string pointed to by strRemoteName. If this member is not NULL, the operating system attempts to make a connection only to the named network provider. You should set this member only if you know for sure which network provider you want to use. Otherwise, let the operating system determine which provider the network name maps to. |
The WNetAddConnection2 function ignores the other members of the NETRESOURCE structure.
The second parameter expected by WNetAddConnection2, strPassword, is a string that specifies a password to be used in making the network connection, if one is required. If this string is NULL, the function uses the current default password associated
with the user specified by strUserName. If strPassword is an empty string, the function does not use a password.
The third parameter, strUsername, is a string that specifies a user name to be used in making the connection. If strUserName is NULL, the function uses the resource's default user name. The strUserName parameter is specified when users want to connect
to a network resource for which they have been assigned a user name or account other than the default user name or account.
The final parameter, lngConnect, is used to specify connection options. When this parameter is set to CONNECT_UPDATE_PROFILE, the network resource connection is remembered, and Windows automatically attempts to restore the connection when the user logs
on. If this parameter is 0, the user's profile is not updated and Windows will not automatically restore the connection at logon.
As with other WNet* functions, the return value, lngRetVal, is ERROR_SUCCESS if the function is successful in making the connection. If the function fails, the return value is an error code from one of the ERROR CODE tables in this chapter. Table 38.5
describes two additional errors associated with this function.
Constant |
Meaning |
ERROR_BUSY |
The router or provider is busy, possibly congested or initializing. The function should be retried. |
ERROR_CANCELLED |
The connection attempt was canceled by the user through a dialog box from one of the network resource providers, or by a called resource or other process. |
Finally, Listing 38.6 shows how your new form's cmdConnect Click event might look if you were using WNetAddConnection2 to connect to a network disk resource and make the connection persistent.
Private Sub cmdConnect_Click() Dim ServerText As String, PassWordText As String Dim DriveLetter As String, UserName As String Dim Msg As String Dim Succeed As Long Dim nrConnect As NETRESOURCE ' Get NETRESOURCE var. nrConnect.lngType = RESOURCETYPE_DISK ' Set resource type. nrConnect.strLocalName = txtDrive ' Get drive letter. nrConnect.strRemoteName = UCase$(txtNetPath) ' Path to resource. nrConnect.strProvider = "" ' Unknown provider. PassWordText = txtPassword ' Get password. UserName = "" ' Default user. Succeed = WNetAddConnection2(nrConnect, PassWordText, UserName, CONNECT_UPDATE_PROFILE) ' Here's the call, all on one line. ' Set the last parameter to 0, if you ' don't want a persistent connection. If IsSuccess(Succeed, Msg) = True Then Drive1.Refresh Else MsgBox Msg, , "Visual Basic Unleashed!" End If End Sub
The WNetCancelConnection2 function is very similar to WNetCancelConnection, but has a little more punch. WNetCancelConnection2 requires three arguments. The first is the resource identifier; the second is either 0 or CONNECT_UPDATE_PROFILE; and the
third indicates whether the connection should be broken if files are open or processes are uncompleted.
Listing 38.7 shows how you might use WNetCancelConnection2 to break a connection during the current session, and not have any effect on that connection's persistence (or lack of persistence) at the next logon.
Private Sub cmdDisconnect_Click() Dim DriveLetter As String, Msg As String Dim Succeed As Long DriveLetter = Mid$(Drive1.Drive, 1, 2) ' Get drive letter from list. ' You might want to get this ' from the txtDrive TextBox ' instead. Succeed = WNetCancelConnection2(DriveLetter,0,False) ' Don't update the ' user's connection ' profile, and ' don't force the ' break if files ' are open. If IsSuccess(Succeed, Msg) = True Then Drive1.Refresh Else MsgBox Msg, , "Visual Basic Unleashed!" End If End Sub
The WNetConnectionDialog function displays a general resource browsing dialog box. It's very useful if all you require is a simple, predefined interface for making network connections. WNetConnectionDialog saves you the hassle of having to design and
implement your own dialog box. Listing 38.8 shows how it's used.
lngRetVal = WNetConnectionDialog(hWinHandle,lngResourceType)
The first parameter, hWinHandle, is a handle to the window which will own the dialog box. In Visual Basic, this is simply your calling form's hWnd property. The second parameter, lngResourceType, specifies which type of resource, or resources, to
browse. The value of lngResourceType is one of the RESOURCETYPE constants: RESOURCETYPE_DISK or RESOURCETYPE_PRINT.
If the function succeeds, the return value, lngRetVal, is ERROR_SUCCESS. If the user cancels the dialog box, it is 0xFFFFFFFF, and no connection is made. As usual, the return value is an error code if the function fails.
The WNetDisconnectDialog function displays a general browsing dialog box for breaking current network connections. The syntax and parameters are nearly identical to those of WNetConnectionDialog. Here's how the function is used:
lngRetVal = WNetDisconnectDialog(hWinHandle,lngResourceType)
You now should use the API Text Viewer to paste declarations for these two functions into your VBUCODE module. To test the Connect and Disconnect dialog functions, you'll add a simple form to your current project. Call it frmDialogs and make it the
project's StartUp form. The form consists of two CommandButtons, and a Frame enclosing two OptionButtons, as displayed in Figure 38.6.
FIGURE 38.6. The Connections Dialog Boxes form.
Table 38.6 shows your new form's significant objects and property settings. Use it to complete the visual implementation of frmDialogs.
Visual Basic Object |
Property |
Design Time Setting |
Form |
Name |
frmDialogs |
|
Caption |
Connection Dialog Boxes |
Command Button |
Name |
cmdConnectDialog |
|
Caption |
Open &Connect Dialog |
Command Button |
Name |
cmdDisconnectDialog |
|
Caption |
Open &Disconnect Dialog |
Frame |
Name |
fraResources |
|
Caption |
Select Resource |
OptionButton |
Name |
optDisk |
|
Caption |
Disk Resource |
|
Value |
True |
OptionButton |
Name |
optPrinter |
|
Caption |
Printer Resource |
By now, you probably have discerned the purpose of this form. It enables you to select a resource type, disk, or printer; and then open the corresponding Connect or Disconnect dialog box by clicking the appropriate CommandButton. Listing 38.9 shows the
code for cmdConnectDialog's Click event.
Private Sub cmdConnectDialog_Click() Dim Succeed As Long ' For return value. Dim Resource As Long ' For resource type. If optDisk Then ' If optDisk is True, Resource = RESOURCETYPE_DISK ' use disk constant, Else ' otherwise, Resource = RESOURCETYPE_PRINT ' use print constant. End If Succeed = WNetConnectionDialog(hWnd, Resource) ' Here's the call. ' Notice the use ' of hWnd, the ' calling window's ' handle, which is ' just frmDialogs' ' hWnd property. End Sub
Listing 38.10 shows cmdDisconnectDialog's nearly identical Click event procedure.
Private Sub cmdDisconnectDialog_Click() Dim Succeed As Long Dim Resource As Long If optDisk Then Resource = RESOURCETYPE_DISK Else Resource = RESOURCETYPE_PRINT End If Succeed = WNetDisconnectDialog(hWnd, Resource) End Sub
You're ready to test. Figures 38.7 and 38.8 show some sample sessions.
FIGURE 38.7. The Printer Connect dialog box in action.
FIGURE 38.8. The Disk Disconnect dialog box in action.
The WNetGetUser function retrieves the current network user name, or the user name used to establish a current network connection. Here is WNetGetUser's syntax, followed by a discussion of all parameters:
lngRetVal = WNetGetUser(strLocalName,strUserName,lngBuffer)
Here, strLocalName is a string that specifies the name of the local device to return the user name (for "LPT2" or "L:", for example), or the name of a network resource to which the user has made a connection. If strLocalName is NULL,
Windows returns the name of the current user. If this parameter is a valid network resource and the user is connected to that resource using different names, the network provider might not be able to resolve which user name to return. In this case, the
provider can choose arbitrarily from the possible user names.
The second parameter, strUserName, is a blank-space string variable that receives the user name. It must be big enough to contain the returned user name. The last parameter, lngBuffer, is a long variable that specifies the size, in characters, of the
variable indicated by strUserName. If the call fails because the buffer is too small, the function returns a value equal to the error code constant ERROR_MORE_DATA, and lngBuffer contains the required buffer size.
Again, if the function succeeds, the value returned to lngRetVal is ERROR_SUCCESS. If the function fails, the return value is an error code that can be evaluated and subsequently displayed.
The WNetGetConnection function retrieves the name of the network resource currently associated with a particular local device. Here is how it's used:
lngRetVal = WNetGetConnection(strLocalName,strRemoteName,lngBuffer)
The strLocalName parameter is a string variable that specifies the name of the local device whose network resource name is to be returned.
The second parameter, strRemoteName, is a blank space string variable that receives the remote resource name used to make the connection. The last parameter, lngBuffer, is a long variable that specifies the size, in characters, of the variable indicated
by strRemoteName. If the function is not successful because the lngBuffer is too small, WNetGetConnection returns a value equal to the error code constant ERROR_MORE_DATA, and lngBuffer contains the required buffer size.
As with all the WNet* functions, if WNetGetConnection succeeds, the value returned to lngRetVal is ERROR_SUCCESS.
If the function fails, the return value is one of the previously discussed error codes, which you can capture and display.
In this section, you'll put your understanding of the WNetGetUser and WNetGetConnection functions to use. First, add another form to your current project, call it frmNetInfo, and make it the project's StartUp form.
Now refer to Figure 38.9 and Table 38.7 to complete the visual design of your new form.
FIGURE 38.9. frmNetInfo in Design mode.
Visual Basic Object |
Property |
Design Time Setting |
Form |
Name |
frmNetInfo |
|
Caption |
Network Information Form |
TextBox |
Name |
txtDevice |
|
TabIndex |
0 |
Command Button |
Name |
cmdShowUser |
|
Caption |
Show &User |
|
Default |
True |
Command Button |
Name |
cmdShowResource |
|
Caption |
Show &Resource |
This form enables the user to enter a local device ID, such as LPT1: or Z:, and to receive the user name or network resource name associated with the device. (Don't forget to add the function declarations for WNetGetUser and WNetGetConnection to your
VBUCODE module.) Listing 38.11 shows the code to add to the Click event procedures for cmdShowUser and cmdShowResource.
Private Sub cmdShowUser_Click() Dim GetUser As Long ' For the return value. Dim DeviceID As String ' Local device. Dim UserName As String ' To receive user name. Dim lngName As Long ' User name buffer size. Dim Msg As String ' For MsgBox display. UserName = Space(25) lngName = Len(UserName) DeviceID = txtDevice GetName = WNetGetUser(DeviceID, UserName, lngName) ' The call. 'Now prepare and display the user information. Msg = "Device " + DeviceID + vbCrLf + "Is Being Used By " + UserName MsgBox Msg, , "Network User Information" End Sub
Listing 38.12 shows cmdShowResource's Click event.
Private Sub cmdShowResource_Click() Dim GetResource As Long ' RetVal Dim DeviceID As String ' Local device. Dim ResourceName As String ' For resource name. Dim lngResource As Long ' Buffer size. Dim Msg As String ' For MsgBox. ResourceName = Space(50) lngResource = Len(ResourceName) DeviceID = txtDevice GetResource = WNetGetConnection(DeviceID, ResourceName, lngResource) 'Now prepare and display the resource information. Msg = "Device " + DeviceID + vbCrLf + "Connected To: " + ResourceName MsgBox Msg, , "Network Resource Information" End Sub
Okay, go ahead and test your form on your own network. See Figures 38.10 and 38.11 for sample output. Figure 38.11 shows some resource connection information, as displayed by the frmNetInfo program.
FIGURE 38.10. Network user information.
FIGURE 38.11. Network connection information.
The final function you'll cover in this chapter is the WNetGetLastError function. This function retrieves the most recent extended error code set by a Windows network function. An extended error code is network-specific; that is, it is supplied by a
particular network provider—Novell or Banyan, for example—and therefore contains error information that pertains only to that provider's network protocol.
Here's the syntax for the WNetGetLastError function:
lngRetVal = WNetGetLastError(lngCode,strDesc,lngDesc,strName,lngName)
The first parameter, lngCode, is a long variable that receives the network-specific error code reported by the provider software.
The next parameter, strDesc, receives the string describing the error. The parameter lngDesc specifies the size, in characters, of strDesc. If the variable is too small for the error string, the string is truncated. A variable of at least 256 characters
is recommended.
The fourth parameter, strName, is a string variable that receives the name identifying the network provider that threw the error. The fifth and last parameter, lngName, sets the size, in characters, of the strName parameter.
If the function successfully obtains the last error reported by the network provider, the return value is ERROR_SUCCESS.
WNetGetLastError should be used when any Windows network function returns ERROR_EXTENDED_ERROR. As mentioned earlier, this function returns detailed error information that is network specific, including a string for reporting errors that are not
described by any existing Windows error code.
Now, in this final section, you'll enhance your IsSuccess() function, the simple error handler you created earlier in this chapter so that it can handle extended as well as standard error codes. In the process, you'll create a new custom function called
ExErrorHandler. Listing 38.13 shows you what should be added to your VBUCODE module.
Function ExErrorHandler() As String Dim strRetVal As String ' For returned error message. Dim ExRV As Long ' For value returned by function. Dim ExEC As Long ' Stores the error code. Dim ExED As String ' Stores the error description. Dim ExDS As Long ' The size of description variable. Dim ExPR As String ' Stores the provider name. Dim ExPS As Long ' The size of the provider variable. ExED = Space(256) ' Initial values ExDS = Len(ExED) ExPR = Space(30) ExPS = Len(ExPR) ExRV = WNetGetLastError(ExEC, ExED, ExDS, ExPR, ExPS) ' The call. If ExRV = ERROR_SUCCESS Then ' Check for success. ' If successful, build network ' specific error message to be ' returned to IsSuccess function. strRetVal = "Extended Error Information" + vbCrLf + vbCrLf strRetVal = strRetVal + "Error Code: " + CStr(ExEC) + vbCrLf strRetVal = strRetVal + "Error Description: " + ExED + vbCrLf strRetVal = strRetVal + "Network Provider: " + ExPR Else ' Otherwise, strRetVal = "Unable To Process Extended Error!" ' Return generic msg. End If ExErrorHandler = strRetVal ' Return message to IsSuccess() End Function
Now your new function, ExErrorHandler(), is called from the IsSuccess() function you created near the beginning of this chapter. It is called only when one of your WNet* functions returns an ERROR_EXTENDED_ERROR value. Listing 38.14 shows the code for
IsSuccess(), with the call to ExErrorHandler printed in bold.
Function IsSuccess(ReturnCode As Long, Msg As String) As Boolean If ReturnCode = ERROR_SUCCESS Then IsSuccess = True Else IsSuccess = False Select Case ReturnCode Case ERROR_INVALID_FUNCTION: Msg = "Function is not supported." Case ERROR_OUTOFMEMORY: Msg = "Out of Memory." Case ERROR_BAD_NET_NAME: Msg = "Invalid Network Resource Name." Case ERROR_NO_RESOURCE_NAME: Msg = "Must Enter A Valid Network Resource Name." Case ERROR_INVALID_PASSWORD: Msg = "The Password was Invalid." Case ERROR_ACCESS_DENIED: Msg = "A Security Violation Occurred." Case ERROR_ALREADY_CONNECTED: Msg = "Local Device Already Connected." Case ERROR_CONNECTION_UNAVAIL: Msg = "The Resource Is Not Shared." Case ERROR_ALREADY_ASSIGNED: Msg = "Local Drive Identifier Is In Use." Case ERROR_BAD_USERNAME: Msg = "No Such User." Case ERROR_INVALID_PRINTER_NAME: Msg = "No Such Printer." Case ERROR_LOCAL_DRIVE: Msg = "Can't Disconnect Local Drive." Case ERROR_INTERNAL_ERROR: Msg = "Internal Error!" Case ERROR_EXTENDED_ERROR: ' If Extended error, call Msg = ExErrorHandler() ' ExErrorHandler() for ' processing and building ' a network-specific error ' message. Case Else: Msg = "Unrecognized Error " + Str$(ReturnCode) + "." End Select End If End Function
If you intend to use some version of this function in your applications, don't forget to paste the WNetGetLastError declaration into a standard code module.
In this chapter, you learned that the introduction of Windows 95 and Visual Basic 4.0 has greatly simplified the creation of Windows applications that can take full advantage of the networks on which they run. Now your 32-bit Visual Basic programs can
call the WNet* network functions in the Microsoft Win32 application programming interface (API). These functions enable you to explore and manage mixed-protocol networks without making adjustments for a particular network software or topology. The Win32
network functions therefore enable your Visual Basic applications to be network independent.
You were introduced to all 13 WNet* functions, and you spent some time exploring nine of them in detail. You created a form that enables you to connect and disconnect network resources using WNetAddConnection and WNetCancelConnection, and then you modified that form to use the more powerful WNetAddConnection2 and WNetCancelConnection2 functions. You used WNetConnectionDialog and WNetDisconnectDialog to display predefined dialog boxes for facilitating network connections and disconnections, and you created a Network Information form, using WNetGetUser and WNetGetConnection, which enabled you to retrieve and display network user and resource names. Finally, you used WNetGetLastError to create a custom extended error handler, which enables you to evaluate and display network-specific error information.